﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace AudiPyme.DAL
{
    public class ControlesEmpresaInformeFactory
    {
        //Método que saca los controles actuales de una empresa y los inserta en su tabla de Informe
        public static bool InsertaControlesEmpresaInforme(int IdEmpresa, int IdInforme)
        {
            //Valor de la ejecucion si todo va bien
            bool ok = true;
            ModeloContainer agenteBD = new ModeloContainer();
            List<ControlesEmpresa> ControlesEmpresa = (from ContrEmp in agenteBD.ControlesEmpresaEstablecer
                                                       where ContrEmp.IdEmpresa == IdEmpresa
                                                       select ContrEmp).ToList();
            if (ControlesEmpresa.Count == 0)
            {
                //No se recogieron controles se devuelve un valor de error
                ok = false;
                return ok;
            }
            else
            {
                foreach (ControlesEmpresa ControlEmp in ControlesEmpresa)
                {
                    ControlesEmpresaInforme nuevoControlEmpInf = new ControlesEmpresaInforme();
                    nuevoControlEmpInf.IdInforme = IdInforme;
                    nuevoControlEmpInf.IdControl = ControlEmp.IdControl;
                    nuevoControlEmpInf.IdEmpresa = ControlEmp.IdEmpresa;
                    nuevoControlEmpInf.ValorInforme = ControlEmp.Valor;
                    agenteBD.AddToControlesEmpresaInformeEstablecer(nuevoControlEmpInf);
                }
                agenteBD.SaveChanges();
                return ok;
            }
        }

        //Método que recoge el número de controles por respuesta según el Objetivo de Control de un Informe dado
        public static List<int> RecogeRespControlObjControlInf(int IdInforme, int IdObjControlActual)
        {
            int NumCtrlSI = 0;
            int NumCtrlNO = 0;
            int NumCtrlPARC = 0;
            int NumCtrlNA = 0;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> ControlesObjControl = from ContrInf in agenteBD.ControlesEmpresaInformeEstablecer
                                                     join Contr in agenteBD.ControlesEstablecer on ContrInf.IdControl equals Contr.IdControl
                                                     where Contr.IdObjControl == IdObjControlActual && ContrInf.IdInforme == IdInforme
                                                     select ContrInf.ValorInforme;
            foreach (String ValorControl in ControlesObjControl)
            {
                switch (ValorControl.Trim())
                {
                    case "SI":
                        NumCtrlSI++;
                        break;
                    case "NO":
                        NumCtrlNO++;
                        break;
                    case "PARC":
                        NumCtrlPARC++;
                        break;
                    case "N/A":
                        NumCtrlNA++;
                        break;
                }
            }
            //[0]SI [1]NO [2]PARC [3]N/A
            List<int> LRespContrObjControl = new List<int>();
            LRespContrObjControl.Add(NumCtrlSI);
            LRespContrObjControl.Add(NumCtrlNO);
            LRespContrObjControl.Add(NumCtrlPARC);
            LRespContrObjControl.Add(NumCtrlNA);
            return LRespContrObjControl;
        }


        //Método que elimina de forma permanente, todos los controles de informe asociados a una empresa
        internal static void EliminaTotalControlesInforme(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ControlesEmpresaInforme> ControlesEliminarQuery = from ContrInf in agenteBD.ControlesEmpresaInformeEstablecer
                                                                         join EmpInf in agenteBD.EmpresaInformeEstablecer on ContrInf.IdInforme equals EmpInf.IdInforme
                                                                         where EmpInf.IdEmpresa == IdEmpresa
                                                                         select ContrInf;
            if (ControlesEliminarQuery.Count() != 0)
            {
                foreach (ControlesEmpresaInforme ControlInforme in ControlesEliminarQuery)
                {
                    agenteBD.ControlesEmpresaInformeEstablecer.DeleteObject(ControlInforme);
                }
                agenteBD.SaveChanges();
            }
        }


        //Método que elimina de forma permanente, todos los controles de informe asociados a un informe
        internal static void EliminaControlesInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ControlesEmpresaInforme> ControlesEliminarQuery = from ContrInf in agenteBD.ControlesEmpresaInformeEstablecer
                                                                         where ContrInf.IdInforme == IdInforme
                                                                         select ContrInf;
            if (ControlesEliminarQuery.Count() != 0)
            {
                foreach (ControlesEmpresaInforme ControlInforme in ControlesEliminarQuery)
                {
                    agenteBD.ControlesEmpresaInformeEstablecer.DeleteObject(ControlInforme);
                }
                agenteBD.SaveChanges();
            }
        }
        //Número Controles SI en un Informe
        public static int NumeroControlesSIInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NumeroControlesSI = (from Inf in agenteBD.InformesEstablecer
                                     join ContrInf in agenteBD.ControlesEmpresaInformeEstablecer on Inf.IdInforme equals ContrInf.IdInforme
                                     where ContrInf.ValorInforme.Trim().Equals("SI") && Inf.IdInforme == IdInforme
                                     select ContrInf).Count();
            return NumeroControlesSI;
        }

        //Número Controles NO en un Informe
        public static int NumeroControlesNOInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NumeroControlesNO = (from Inf in agenteBD.InformesEstablecer
                                     join ContrInf in agenteBD.ControlesEmpresaInformeEstablecer on Inf.IdInforme equals ContrInf.IdInforme
                                     where ContrInf.ValorInforme.Trim().Equals("NO") && Inf.IdInforme == IdInforme
                                     select ContrInf).Count();
            return NumeroControlesNO;
        }

        //Número Controles PARC en un Informe
        public static int NumeroControlesPARCInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NumeroControlesPARC = (from Inf in agenteBD.InformesEstablecer
                                       join ContrInf in agenteBD.ControlesEmpresaInformeEstablecer on Inf.IdInforme equals ContrInf.IdInforme
                                       where ContrInf.ValorInforme.Trim().Equals("PARC") && Inf.IdInforme == IdInforme
                                       select ContrInf).Count();
            return NumeroControlesPARC;
        }


        //Número Controles N/A en un Informe
        public static int NumeroControlesNAInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NumeroControlesNA = (from Inf in agenteBD.InformesEstablecer
                                     join ContrInf in agenteBD.ControlesEmpresaInformeEstablecer on Inf.IdInforme equals ContrInf.IdInforme
                                     where ContrInf.ValorInforme.Trim().Equals("N/A") && Inf.IdInforme == IdInforme
                                     select ContrInf).Count();
            return NumeroControlesNA;
        }


        //Método que recoge la evolución en las respuestas de los controles según una lista de Informes para formatear en una tabla
        public static List<ControlesEmpresaInforme> ControlesEvolucionInformes(int IdInformeBase, int IdInformeActual)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Recogemos las respuestas de los controles del Informe Base
            var ControlesInformeBase = (from ContrInf in agenteBD.ControlesEmpresaInformeEstablecer
                                        where ContrInf.IdInforme == IdInformeBase
                                        select new { ContrInf.IdControl, ContrInf.ValorInforme }).OrderBy(c => c.IdControl);
            //Pasamos por cada Informe viendo sus controles y comparándolos con los Informe Base
            var ControlesInformeActual = (from ContrInf in agenteBD.ControlesEmpresaInformeEstablecer
                                          where ContrInf.IdInforme == IdInformeActual
                                          select new { ContrInf.IdControl, ContrInf.ValorInforme }).OrderBy(d => d.IdControl);
            //Sacamos los controles que han cambiado de respuesta
            var ControlesDistintosQuery = ControlesInformeActual.Except(ControlesInformeBase);
            List<ControlesEmpresaInforme> LControlesDistintos = new List<ControlesEmpresaInforme>();
            foreach (var ControlDistinto in ControlesDistintosQuery)
            {
                ControlesEmpresaInforme NuevoElemento = new ControlesEmpresaInforme();
                NuevoElemento.IdControl = ControlDistinto.IdControl;
                NuevoElemento.ValorInforme = ControlDistinto.ValorInforme;
                NuevoElemento.IdEmpresa = 0;
                NuevoElemento.IdInforme = 0;
                LControlesDistintos.Add(NuevoElemento);
            }
            return LControlesDistintos;
        }

        //Método que elimina todas las tuplas de la tabla ControlesEmpresaInforme asociadas a una lista de informes
        internal static void EliminaControlesInformes(List<int> LInformes)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<ControlesEmpresaInforme> ControlesEliminarQuery = from ContrInf in agenteBD.ControlesEmpresaInformeEstablecer
                                                                         where LInformes.Contains(ContrInf.IdInforme)
                                                                         select ContrInf;
            if (ControlesEliminarQuery.Count() != 0)
            {
                foreach (ControlesEmpresaInforme ControlInforme in ControlesEliminarQuery)
                {
                    agenteBD.ControlesEmpresaInformeEstablecer.DeleteObject(ControlInforme);
                }
                agenteBD.SaveChanges();
            }
        }
    }
}
